[T-SQL] Cursor範例


Posted by mike-hsieh on 2023-04-12

以下用程式碼說明 Cursor 的基本使用範例(北風資料庫):

/*
    Cursor範例: 訂單明細中 (金額 * 數量) 的 加總
*/

--  當前一筆資料的 (金額 * 數量)。初始值為0
DECLARE @ProdCost money = 0;        
--  總 (金額 * 數量)。初始值為0
DECLARE @ProdCostTotal money = 0;   

--定義游標變數
DECLARE MyCursor CURSOR FOR
    SELECT TOP 10 UnitPrice * Quantity  
    FROM [Northwind].[dbo].[Order Details]

--開啟游標。此時 @@FETCH_STATUS = -1
OPEN MyCursor

--推進游標,並將資料存到 @ProdCost 裡面。 此時 @@FETCH_STATUS = 0
FETCH NEXT FROM MyCursor INTO @ProdCost

--While迴圈。 @@FETCH_STATUS 為游標的狀態屬性(0: 尚未結束, -1: 結束)
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @ProdCostTotal = @ProdCostTotal + @ProdCost --推進游標,並將資料存到 @ProdCost 裡面。
    FETCH NEXT FROM MyCursor INTO @ProdCost --推進游標,並將資料存到 @ProdCost 裡面。
END

--關閉游標。 (While迴圈結束)
CLOSE MyCursor

--釋放游標
DEALLOCATE MyCursor

--輸出總金額
SELECT @ProdCostTotal ProdCostTotal

這邊分析了細部的拆解步驟,我們這次不跑迴圈,手動執行 Cursor:
Step1: 先釋放游標

--釋放游標
DEALLOCATE MyCursor

Step2: 定義游標變數

--定義游標變數
DECLARE MyCursor CURSOR FOR
    SELECT TOP 10 UnitPrice * Quantity  
    FROM [Northwind].[dbo].[Order Details]

Step3: 開啟游標

--開啟游標。此時 @@FETCH_STATUS = -1
OPEN MyCursor

Step4: 手動推進游標

--  當前一筆資料的 (金額 * 數量)。初始值為0
DECLARE @ProdCost money = 0;        

--推進游標,並將資料存到 @ProdCost 裡面。
FETCH NEXT FROM MyCursor INTO @ProdCost

--輸出總金額
SELECT @ProdCost AS 當前的金額, @@FETCH_STATUS AS 游標狀態

可以發現每次執行 Step4 都會推進一次游標,這就是游標的運作方式。

參考:

  1. https://medium.com/ricos-note/sql-server-盡量避免使用cursor-f166fce5e063

#MSSQL #tsql #cursor







Related Posts

轉職前端工程師之路 Day4

轉職前端工程師之路 Day4

[Note] React: React Router DOM v 6.3.X

[Note] React: React Router DOM v 6.3.X

[BE101]  留言板(中-修正問題篇)

[BE101] 留言板(中-修正問題篇)


Comments